package com.zn.opit.videoframe.utils;

import com.zn.opit.videoframe.exception.VideoFrameException;
import com.zn.opit.videoframe.exception.VideoFrameExceptionTypes;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.disk.DiskFileItem;
import org.apache.commons.lang3.StringUtils;
import org.jcodec.api.FrameGrab;
import org.jcodec.api.JCodecException;
import org.jcodec.common.model.Picture;
import org.jcodec.scale.AWTUtil;
import org.springframework.http.MediaType;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.commons.CommonsMultipartFile;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.*;
import java.util.Arrays;
import java.util.List;

@Slf4j
public class VideoUtil {

    private static final List<String> videoSuffix = Arrays.asList(
            "avi", "wmv", "mov", "mpg", "mpeg", "rm", "ram", "flv", "swf", "mp4"
    );

    public static MultipartFile getFirstFrame(MultipartFile videoFile) {
        return getFrame(videoFile, 1);
    }

    public static MultipartFile getFrame(MultipartFile multipartFile, int frameNumber) {
        String originalFilename = multipartFile.getOriginalFilename();
        if (StringUtils.isBlank(originalFilename) || !originalFilename.contains(".")) {
            throw new VideoFrameException(VideoFrameExceptionTypes.NOT_SUPPORTED_FILE_TYPE);
        }
        String[] filenameSplit = originalFilename.split("\\.");
        if (!videoSuffix.contains(filenameSplit[filenameSplit.length - 1])) {
            throw new VideoFrameException(VideoFrameExceptionTypes.NOT_SUPPORTED_FILE_TYPE);
        }
        CommonsMultipartFile cf = (CommonsMultipartFile) multipartFile;
        DiskFileItem fi = (DiskFileItem) cf.getFileItem();
        File file = fi.getStoreLocation();
        MultipartFile videoCover = null;
        try {
            Picture pic = FrameGrab.getFrameFromFile(file, frameNumber);
            BufferedImage bi = AWTUtil.toBufferedImage(pic);
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            ImageIO.write(bi, MediaType.IMAGE_JPEG.getSubtype(), baos);
            InputStream input = new ByteArrayInputStream(baos.toByteArray());
            FileItem fileItem = FileUtil.createFileItem(input);
            videoCover = new CommonsMultipartFile(fileItem);
        } catch (IOException | JCodecException e) {
            log.error("获取视频帧出现异常", e);
            throw new VideoFrameException(VideoFrameExceptionTypes.GET_VIDEO_FRAME_FAILED);
        }
        return videoCover;
    }
}
